"""Command implementations for the task manager CLI."""

import sys
from typing import List
from .models import TaskManager, TaskStatus
from .storage import TaskStorage
from .parser import TaskParser


class CommandHandler:
    """Handles all CLI commands."""
    
    def __init__(self):
        self.storage = TaskStorage()
        self.parser = TaskParser()
    
    def add_tasks(self, task_names: str) -> None:
        """Handle add command: task-manager add taskname1, taskname2, taskname3"""
        task_manager = self.storage.load_tasks()
        
        # Parse comma-separated task names
        tasks = self.parser.parse_comma_separated_tasks(task_names)
        
        if not tasks:
            print("No valid tasks found to add.")
            return
        
        added_count = 0
        for task_name in tasks:
            task = task_manager.add_task(task_name)
            print(f"Added task {task.id}: {task.name}")
            added_count += 1
        
        self.storage.save_tasks(task_manager)
        print(f"Successfully added {added_count} task(s).")
    
    def auto_add_tasks(self) -> None:
        """Handle auto-add command: interactive task input with parsing"""
        print("Enter tasks (one per line). Press Ctrl+C or Ctrl+D to finish:")
        
        task_manager = self.storage.load_tasks()
        lines = []
        
        try:
            while True:
                try:
                    line = input()
                    if line.strip():  # Only add non-empty lines
                        lines.append(line)
                except EOFError:
                    break
        except KeyboardInterrupt:
            pass
        
        if not lines:
            print("No input received.")
            return
        
        # Parse all lines as multi-line text
        text = '\n'.join(lines)
        parsed_tasks = self.parser.parse_multi_line_text(text)
        
        if not parsed_tasks:
            print("No valid tasks found in the input.")
            return
        
        added_count = 0
        for task_name, status in parsed_tasks:
            task = task_manager.add_task(task_name, status)
            status_str = status.value.upper()
            print(f"Added task {task.id}: {task.name} ({status_str})")
            added_count += 1
        
        self.storage.save_tasks(task_manager)
        print(f"Successfully added {added_count} task(s).")
    
    def list_tasks(self) -> None:
        """Handle list command: show all tasks with IDs and status"""
        task_manager = self.storage.load_tasks()
        
        if not task_manager.tasks:
            print("No tasks found.")
            return
        
        print("Tasks:")
        for task in sorted(task_manager.tasks, key=lambda t: t.id):
            status_symbol = {
                TaskStatus.TODO: "☐",
                TaskStatus.DONE: "☒", 
                TaskStatus.SKIPPED: "⊘"
            }[task.status]
            
            print(f"{task.id:3d}. {status_symbol} {task.name} ({task.status.value.upper()})")
    
    def mark_tasks_done(self, task_ids: str) -> None:
        """Handle done command: mark tasks as completed"""
        task_manager = self.storage.load_tasks()
        
        # Parse comma-separated task IDs
        ids = []
        for id_str in task_ids.split(','):
            try:
                ids.append(int(id_str.strip()))
            except ValueError:
                print(f"Invalid task ID: {id_str.strip()}")
                return
        
        success_count = 0
        for task_id in ids:
            if task_manager.mark_done(task_id):
                task = task_manager.get_task_by_id(task_id)
                print(f"Marked task {task_id} as done: {task.name}")
                success_count += 1
            else:
                print(f"Task {task_id} not found or already completed.")
        
        if success_count > 0:
            self.storage.save_tasks(task_manager)
            print(f"Successfully marked {success_count} task(s) as done.")
    
    def mark_task_undo(self, task_id: str) -> None:
        """Handle undo command: mark task as todo"""
        try:
            task_id = int(task_id)
        except ValueError:
            print(f"Invalid task ID: {task_id}")
            return
        
        task_manager = self.storage.load_tasks()
        
        if task_manager.mark_undo(task_id):
            task = task_manager.get_task_by_id(task_id)
            print(f"Marked task {task_id} as todo: {task.name}")
            self.storage.save_tasks(task_manager)
        else:
            print(f"Task {task_id} not found.")
    
    def delete_task(self, task_id: str) -> None:
        """Handle delete command: remove specific task"""
        try:
            task_id = int(task_id)
        except ValueError:
            print(f"Invalid task ID: {task_id}")
            return
        
        task_manager = self.storage.load_tasks()
        task = task_manager.get_task_by_id(task_id)
        
        if task and task_manager.delete_task(task_id):
            print(f"Deleted task {task_id}: {task.name}")
            self.storage.save_tasks(task_manager)
        else:
            print(f"Task {task_id} not found.")
    
    def delete_all_tasks(self) -> None:
        """Handle delete --all command: remove all tasks"""
        task_manager = self.storage.load_tasks()
        count = len(task_manager.tasks)
        
        if count == 0:
            print("No tasks to delete.")
            return
        
        task_manager.delete_all_tasks()
        self.storage.save_tasks(task_manager)
        print(f"Deleted all {count} task(s).")
    
    def show_next_task(self) -> None:
        """Handle next command: show progress and advance to next task"""
        task_manager = self.storage.load_tasks()
        
        # Get completed tasks from benchmark point
        completed_tasks = task_manager.get_completed_tasks_from_benchmark()
        skipped_tasks = task_manager.get_skipped_tasks()
        next_task = task_manager.get_next_todo_task()
        
        # Build progress message
        message_parts = []
        
        if completed_tasks:
            completed_names = [f"{t.name}" for t in completed_tasks]
            if len(completed_names) > 5:  # Truncate if too many
                displayed = completed_names[:3]
                remaining = len(completed_names) - 3
                completed_str = ", ".join(displayed) + f", ... (and {remaining} more)"
            else:
                completed_str = ", ".join(completed_names)
            message_parts.append(f"I have finished the tasks: {completed_str}")
        
        if skipped_tasks:
            skipped_names = [f"{t.name}" for t in skipped_tasks]
            skipped_str = ", ".join(skipped_names)
            if message_parts:
                message_parts.append(f"as well as skipped {skipped_str}")
            else:
                message_parts.append(f"I have skipped: {skipped_str}")
        
        if next_task:
            if message_parts:
                message_parts.append(f"Now, continue to do the task: {next_task.name}")
            else:
                message_parts.append(f"Next task: {next_task.name}")
            
            # Mark the next task as done
            task_manager.mark_done(next_task.id)
            self.storage.save_tasks(task_manager)
        else:
            if message_parts:
                message_parts.append("All tasks are completed!")
            else:
                message_parts.append("No tasks available.")
        
        print(". ".join(message_parts) + ".")
    
    def show_prev_task(self) -> None:
        """Handle prev command: reverse last completion"""
        task_manager = self.storage.load_tasks()
        
        if task_manager.reverse_last_completion():
            # Get the task that was just undone
            if task_manager.completion_history:
                # The last item in completion_history before reversal
                pass
            print("Reversed the last task completion.")
            self.storage.save_tasks(task_manager)
        else:
            print("No recent completions to reverse.")
    
    def set_benchmark(self, task_id: str) -> None:
        """Handle benchmark command: set starting point for progress messages"""
        try:
            task_id = int(task_id)
        except ValueError:
            print(f"Invalid task ID: {task_id}")
            return
        
        task_manager = self.storage.load_tasks()
        
        if task_manager.set_benchmark(task_id):
            task = task_manager.get_task_by_id(task_id)
            print(f"Set benchmark at task {task_id}: {task.name}")
            self.storage.save_tasks(task_manager)
        else:
            print(f"Task {task_id} not found.")